package single_game.logic.race_simulator;

import java.util.ArrayList;

import javax.swing.JFrame;

import single_game.gui.RaceGui;
import single_game.logic.race_simulator.race_team.MyTeamSimulator;
import single_game.logic.race_simulator.race_team.RaceRider;
import single_game.logic.race_simulator.race_team.RaceTeamSimulator;
import single_game.logic.stage_generator.GenerateStage;

public class Race extends Thread {
	
	public ArrayList<RaceRider> otherTeams[], myTeam;
	private ArrayList<RaceTeamSimulator> raceTeams;
	private MyTeamSimulator myTeamSimulator;
	private Boolean raceGoOn = true;
	private RaceGui raceGui;
	private int time = 0, 
				stageLength = 5000;
	public int stageSpeed = 1;
	public int stage[];
	private String stageType = "Mountain";
	private static volatile Race instance;
	
	public Race(ArrayList<RaceRider> myTeam, ArrayList<RaceRider>[] otherTeams, JFrame frame, int maxRiders) {
		
		this.otherTeams = otherTeams;
		this.myTeam = myTeam;
		raceGui = new RaceGui(frame, otherTeams.length*maxRiders, myTeam);
		
		start();	
	}
	
	
	public void run() {
		
		raceTeams = new ArrayList<RaceTeamSimulator>(otherTeams.length);	
		stage = GenerateStage.generate(stageLength, stageType);
			
		ArrayList<RaceRider> peleton = new ArrayList<RaceRider>();

		//Creating Team Simulator objects
		for (int i = 0; i < otherTeams.length; i++) {
			raceTeams.add(new RaceTeamSimulator(otherTeams[i]));
			raceTeams.get(i).newStage();
		}
			

		myTeamSimulator = new MyTeamSimulator(myTeam);
		myTeamSimulator.newStage();
		for (int i = 0; i < myTeam.size(); i++) {
			peleton.add(myTeam.get(i));
		}

		//Creating main group with groupId = 100 (peleton)
		for (int i = 0; i < otherTeams.length; i++) {
			for (int j = 0; j < otherTeams[i].size(); j++) {
				peleton.add(otherTeams[i].get(j));
			}		
		}

		
		RaceSimulator simulator = new RaceSimulator(peleton);
				
		while (raceGoOn) {
			long startTime = System.currentTimeMillis();
			
			for (int i = 0; i < raceTeams.size(); i++)
				raceTeams.get(i).makeDecision();
			
			myTeamSimulator.makeDecision();
			
			simulator.ride();		
			
			if (time%10 == 0) {
				raceGui.refresh(simulator);
			}
			
			try {
				long usedTime = System.currentTimeMillis() - startTime;
				long stageFrameTime = 100/(2*stageSpeed);
				if (usedTime < stageFrameTime)
					Thread.sleep(stageFrameTime - usedTime);
			} 
			catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			time++;
		}	
	}
	
	public static synchronized Race getInstance(){
		 return instance;
	 }
	
	
	public static synchronized Race makeInstance(ArrayList<RaceRider> myTeam, ArrayList<RaceRider>[] otherTeams, JFrame frame, int maxRiders) {
		 if(instance == null){
			 synchronized(Race.class){
				 if(instance == null){
					 instance = new Race(myTeam, otherTeams, frame, maxRiders);
	             }
			 }
		 }
		 return instance;
	}
	
}
